package com.gingersoft.connect.utils

import android.util.Log
import com.gingersoft.connect.SendCallback
import com.gingersoft.connect.bean.MessageBuilder
import com.gingersoft.connect.bean.SocketCallbackBean
import org.java_websocket.client.WebSocketClient
import org.java_websocket.drafts.Draft_6455
import org.java_websocket.handshake.ServerHandshake
import java.net.ConnectException
import java.net.URI
import java.util.Timer
import java.util.TimerTask

class MyWebSocketClient(
    serverUri: URI,
    connectOutTime: Int,
    private val listener: GingerSoftConnect.SocketStateListener?
) :
    WebSocketClient(serverUri, Draft_6455(), null, connectOutTime) {

    private val map by lazy { HashMap<String, SendCallback>() }
    private val timerMap by lazy { HashMap<String, Timer>() }

    private var status = 0

    override fun onOpen(handshakedata: ServerHandshake?) {
        listener?.onOpen()
        status = 1
    }

    override fun onMessage(message: String?) {
        val bean = GsonUtils.GsonToBean(message, SocketCallbackBean::class.java)
        Log.e("eeeaaa", "客戶端收到消息:$message")
        if (bean != null && map.containsKey(bean.msgCode)) {
            map[bean.msgCode]?.callback(bean.success, bean.statusCode, bean.errorMsg)
            map[bean.msgCode]?.callback(bean)
            timerMap[bean.msgCode]?.cancel()
            map.remove(bean.msgCode)
            timerMap.remove(bean.msgCode)
        }
    }

    override fun onClose(code: Int, reason: String?, remote: Boolean) {
//        = if(reason!=null && reason.contains("failed to connect")){
//            onError(ConnectException(reason))
//            3
//        } else {
        listener?.onClose(code, reason, remote)
        status = 2
        //            2
//        }
    }

    override fun onError(ex: Exception?) {
        listener?.onError(ex)
        status = 3
    }

    fun sendMsg(msgCode: String, text: String, callback: SendCallback?) {
        if (callback != null) {
            // 保存code和callback的關係，服務器返回收到後，需要調用回調
            // 使用map是為了應對多線程情況
            map[msgCode] = callback
            // 增加十秒倒計時，超時情況
            timerMap[msgCode] = Timer()
            timerMap[msgCode]?.schedule(object : TimerTask() {
                override fun run() {
                    if (!cancel()) {
                        callback.callback(
                            false,
                            MessageBuilder.ERROR_CODE_SEND_TIMEOUT,
                            "接收服務端響應超時"
                        )
                    }
                }
            }, 10000)
        }
        // 發送數據到服務器
        send(text)
    }

    fun getStatus() = status
}